package org.xqh.study.jna.guanglian;

import com.sun.jna.Callback;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;

/**
 * @ClassName GlModel
 * @Description TODO
 * @Author xuqianghui
 * @Date 2023/3/27 13:05
 * @Version 1.0
 */
public class GlModel {

    /**
     * 配置项
     */
    @FieldOrder({"server_host", "server_port", "use_tls", "cert_path", "twauth_pem_path"})
    public static class GlpServerModel extends Structure {

        public String server_host;
        public int server_port;
        public int use_tls;/* 使用使用tls连接 */

        public String cert_path;/* 使用tls连接时，指定证书文件，可选 */

        public String twauth_pem_path;/* 双向认证公钥文件 */


        public static class ByReference extends GlpServerModel implements Structure.ByReference {
        }

        public static class ByValue extends GlpServerModel implements Structure.ByValue {
        }


    }


    @FieldOrder({"sip_server", "stun_server", "aes_size", "log_lev", "log_max_size", "log_path"})
    public static class CfgInitModel extends Structure {

        public GlpServerModel sip_server;
        public GlpServerModel stun_server;

        public int aes_size;/* 0: none, 128/192/256: aes_key_size */

        /* lib log info */
        public int log_lev;/* 0:trace,1:debug,2:info,3:warn,4:error,5:null */
        public int log_max_size;
        public String log_path;


        public static class ByReference extends CfgInitModel implements Structure.ByReference {
        }

        public static class ByValue extends CfgInitModel implements Structure.ByValue {
        }
    }


    /**
     * 客户端sdk启动参数
     */
    @FieldOrder({"local_peerid"})
    public static class GlCliStartParamStruct extends Structure {

        public String local_peerid;

        public static class ByReference extends GlCliStartParamStruct implements Structure.ByReference {
        }

        public static class ByValue extends GlCliStartParamStruct implements Structure.ByValue {
        }
    }


    @FieldOrder({"local_peerid", "someone_callme_cb"})
    public static class GlDevStartParamStruct extends Structure {

        public String local_peerid;

        public DeviceCallback someone_callme_cb;

        public static class ByReference extends GlDevStartParamStruct implements Structure.ByReference {
        }

        public static class ByValue extends GlDevStartParamStruct implements Structure.ByValue {
        }
    }


    @FieldOrder({"remote_peerid", "timeout_sec", "connected_cb", "disconnect_cb", "recv_msg_cb"})
    public static class GldAcceptParamStruct extends Structure {

        public String remote_peerid;

        public int timeout_sec;

        public ConnectedCallback connected_cb;
        public DisconnectedCallback disconnect_cb;
        public ReceiveMsgCallback recv_msg_cb;

        public static class ByReference extends GldAcceptParamStruct implements Structure.ByReference {
        }

        public static class ByValue extends GldAcceptParamStruct implements Structure.ByValue {
        }
    }



    /**
     * 任意一种tunnel_type连接成功时，回调通知上层
     * 只通知一次，即当有其他tunnel连接成功，不会再回调通知
     */
    public interface ConnectedCallback extends Callback {
        void connectedCall(String remote_peerid, int tunnel_type);
    }

    /**
     */
    public interface DeviceCallback extends Callback {
        void callback(String remote_peerid, String accessToken);
    }

    public static class DeviceCallbackImpl implements DeviceCallback {
        public GLLibrary instance;
        @Override
        public void callback(String remote_peerid, String accessToken) {//account#pwd
            System.out.println("设备端回调. remote_peerid: " + remote_peerid + ", accessToken: " + accessToken);
            GldAcceptParamStruct.ByReference struct = new GldAcceptParamStruct.ByReference();
            struct.remote_peerid = remote_peerid;
            struct.timeout_sec = 10;
            ConnectedCallback connectCb = new ConnectedCallbackImpl();
            DisconnectedCallback disconnectCb = new DisconnectedCallbackImpl();
            ReceiveMsgCallback receiveMsgCb = new ReceiveMsgCallbackImpl();
            struct.connected_cb = connectCb;
            struct.disconnect_cb = disconnectCb;
            struct.recv_msg_cb = receiveMsgCb;
            int ret = instance.gld_accept(struct);
            System.out.println("accept client connect. " + remote_peerid);
        }
    }

    public static class ConnectedCallbackImpl implements ConnectedCallback {
        @Override
        public void connectedCall(String remote_peerid, int tunnel_type) {
            System.out.println("连接成功, 设备ID: " + remote_peerid + ", 连接类型: " + tunnel_type);
        }
    }


    public interface DisconnectedCallback extends Callback {
        void disconnectedCall(String remote_peerid, int tunnel_type);
    }

    public static class DisconnectedCallbackImpl implements DisconnectedCallback {
        @Override
        public void disconnectedCall(String remote_peerid, int tunnel_type) {
            System.out.println("断开连接, 设备成功. ID: " + remote_peerid + ", 连接类型: " + tunnel_type);
        }
    }


    /**
     * 消息送达
     */
    public interface ReceiveMsgCallback extends Callback {
        void receiveMsgCall(String remote_peerid, int tunnel_type, String msg, int size);
    }

    public static class ReceiveMsgCallbackImpl implements ReceiveMsgCallback {
        @Override
        public void receiveMsgCall(String remote_peerid, int tunnel_type, String msg, int size) {
            System.out.println("消息送达, 设备成功. ID: " + remote_peerid + ", 连接类型: " + tunnel_type + ", msg: " + msg + ", size: " + size);
        }
    }


    /**
     * 建立连接参数
     */
    @FieldOrder({"remote_peerid", "access_token", "timeout_sec", "connected_cb", "disconnect_cb", "recv_msg_cb", "user_data"})
    public static class GlcConnectParamStruct extends Structure {
        public String remote_peerid;
        public String access_token; //设备端鉴权
        public int timeout_sec;//超时时间
        public ConnectedCallback connected_cb;
        public DisconnectedCallback disconnect_cb;
        public ReceiveMsgCallback recv_msg_cb;

        public Pointer user_data;

        public static class ByReference extends GlcConnectParamStruct implements Structure.ByReference {
        }

        public static class ByValue extends GlcConnectParamStruct implements Structure.ByValue {
        }
    }


    /**
     * 启动端口映射参数
     */
    @FieldOrder({"remote_peerid", "listen_port", "destination_port", "destination_host", "rule"})
    public static class GlcSvmapParamStruct extends Structure {
        public String remote_peerid;
        public int listen_port;
        public int destination_port;// 目标端口, 用于指定设备端需要访问的端口
        public String destination_host; // 目标主机，用于指定设备端需要访问的地址，访问访问 设备本机时传"127.0.0.1"或者NULL
        public int rule; // 附加的映射规则

        public static class ByReference extends GlcSvmapParamStruct implements Structure.ByReference {
        }

        public static class ByValue extends GlcSvmapParamStruct implements Structure.ByValue {
        }

    }

    /**
     * 连接状态信息查询
     */
    @FieldOrder({"remote_peerid", "tunnel_direct_state", "tunnel_relay_state", "tunnel_lan_state", "tunnel_nptt_state", "rt_send_kbps", "rt_recv_kbps"})
    public static class GlPeerInfoStruct extends Structure {
        public String remote_peerid;
        public int tunnel_direct_state;
        public int tunnel_relay_state;
        public int tunnel_lan_state;
        public int tunnel_nptt_state;
        public int rt_send_kbps;/* 与remote_peerid连接的实时传输速度 */
        public int rt_recv_kbps;

        public static class ByReference extends GlPeerInfoStruct implements Structure.ByReference {
        }

        public static class ByValue extends GlPeerInfoStruct implements Structure.ByValue {
        }

    }
}
